package info.macnana.online.core.redis.impl;

import info.macnana.online.core.redis.CommonRedisDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Array;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * author: zhengheng
 * github: https://github.com/macnana777
 * email: 517862340@qq.com
 * <p>
 * Date: 2017-08-01 14:58
 * Description:
 * Copyright(©) 2017 by zhengheng.
 */
@Repository
public class CommonRedisDaoImpl<T> implements CommonRedisDao<T>{

    @Autowired
    private RedisTemplate<String,T> redisTemplate;

    private static Logger LOGGER = LoggerFactory.getLogger(CommonRedisDaoImpl.class);

    /**
     * 获取缓存操作
     * @param key
     * @param value
     * @param time
     * @return
     */
    @Override
    public boolean cacheValue(String key, T value, long time) {
        key = "";
        try{
            ValueOperations<String,T> valueOperations  = redisTemplate.opsForValue();
            if(time > 0) {
                valueOperations.set(key,value,time, TimeUnit.SECONDS);
            }
            return true;
        }catch (Exception e){
            LOGGER.error("缓存 key: {} 失败 ，value : {} ",key,value,e);
        }
        return false;
    }

    @Override
    public boolean cacheValue(String key, T value) {
        return cacheValue(key,value,-1);
    }

    @Override
    public boolean containsValueKey(String key) {
        return containsKey(key);
    }

    @Override
    public boolean containsSetKey(String key) {
        return containsKey(key);
    }

    @Override
    public boolean containsListKey(String key) {
        return containsKey(key);
    }

    @Override
    public boolean containsKey(String key) {
        try{
            return redisTemplate.hasKey(key);
        }catch (Exception ex){
            LOGGER.error("判断缓存存在失败key: {}, Codeor : {}" , key ,ex);
        }
        return false;
    }

    @Override
    public T getValue(String key) {
        try {
            ValueOperations<String, T> valueOps = redisTemplate.opsForValue();
            return valueOps.get(key);
        } catch (Exception ex) {
            LOGGER.error("获取缓存失败key:{},Codeor:{}",key,ex);
        }
        return null;
    }

    @Override
    public boolean removeValue(String key) {
        try {
            redisTemplate.delete(key);
            return true;
        } catch (Exception ex) {
            LOGGER.error("删除缓存失败key:{}, Codeor : {}" ,key ,ex);
        }
        return false;
    }

    @Override
    public boolean removeSet(String key) {
        return removeValue(key);
    }

    @Override
    public boolean removeList(String key) {
        return removeValue(key);
    }

    @Override
    public boolean cacheSet(String key, T value, long time) {
        try{
            SetOperations<String, T> setOps = redisTemplate.opsForSet();
            setOps.add(key,value);
            if (time > 0) redisTemplate.expire(key, time, TimeUnit.SECONDS);
            return true;
        }catch (Exception ex){
            LOGGER.error("缓存key:{}失败, value : {} ",key,value , ex);
        }
        return false;
    }

    @Override
    public boolean cacheSet(String key, T value) {
        return cacheSet(key, value, -1);
    }

    @Override
    public boolean cacheSet(String key, Set<T> value, long time) {
        try {
            SetOperations<String, T> setOps = redisTemplate.opsForSet();
            setOps.add(key,value.toArray((T[]) new Object[value.size()]));
            if (time > 0) redisTemplate.expire(key, time, TimeUnit.SECONDS);
            return true;
        } catch (Exception ex) {
            LOGGER.error("缓存key:{}失败, value : {} ",key,value,ex);
        }
        return false;
    }

    @Override
    public boolean cacheSet(String key, Set<T> value) {
        return cacheSet(key,value);
    }

    @Override
    public Set<T> getSet(String key) {
        try {
            SetOperations<String, T> setOps = redisTemplate.opsForSet();
            return setOps.members(key);
        } catch (Exception ex) {
            LOGGER.error("获取set缓存key:{}失败, Codeor : {}",ex);
        }
        return null;
    }

    @Override
    public boolean cacheList(String key, T value, long time) {
        try {
            ListOperations<String, T> listOps = redisTemplate.opsForList();
            listOps.rightPush(key, value);
            if (time > 0) redisTemplate.expire(key, time, TimeUnit.SECONDS);
            return true;
        } catch (Exception ex) {
            LOGGER.error("缓存key:{}失败, value : {} ",key,value,ex);
        }
        return false;
    }

    @Override
    public boolean cacheList(String key, T value) {
        return cacheList(key, value, -1);
    }

    @Override
    public boolean cacheList(String key, List<T> value, long time) {
        try {
            ListOperations<String, T> listOps = redisTemplate.opsForList();
            listOps.rightPushAll(key, value);
            if (time > 0) redisTemplate.expire(key, time, TimeUnit.SECONDS);
            return true;
        } catch (Exception ex) {
            LOGGER.error("缓存key:{}失败, value : {} ",key,value,ex);
        }
        return false;
    }

    @Override
    public boolean cacheList(String key, List<T> value) {
        return cacheList(key, value, -1);
    }

    @Override
    public List<T> getList(String key, long start, long end) {
        try {
            ListOperations<String, T> listOps = redisTemplate.opsForList();
            return listOps.range(key, start, end);
        } catch (Exception ex) {
            LOGGER.error("获取list缓存失败key:{},Codeor:{}",key,ex);
        }
        return null;
    }

    @Override
    public long getListSize(String key) {
        try {
            ListOperations<String, T> listOps = redisTemplate.opsForList();
            return listOps.size(key);
        } catch (Exception ex) {
            LOGGER.error("获取list长度失败key:{}, Codeor:{}",key,ex);
        }
        return 0;
    }

    @Override
    public long getListSize(ListOperations<String, T> listOps, String key) {
        try {
            return listOps.size(key);
        } catch (Exception ex) {
            LOGGER.error("获取list长度失败key:{}, Codeor:{}",key,ex);
        }
        return 0;
    }

    @Override
    public boolean removeOneOfList(String key) {
        try {
            ListOperations<String, T> listOps = redisTemplate.opsForList();
            listOps.rightPop(key);
            return true;
        } catch (Exception ex) {
            LOGGER.error("移除list缓存失败key:{}, Codeor:{}",key,ex);
        }
        return false;
    }
}
